home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mint96sb.zoo / src / context.spp < prev    next >
Encoding:
Text File  |  1992-10-05  |  6.4 KB  |  180 lines

  1. %include "magic.i"
  2. ;
  3. ; routines for saving/restoring user contexts
  4. ;
  5. ; long build_context(struct context *sav, short fmt):
  6. ;    Called from an interrupt handler (such as the trap #1 routine
  7. ;    for system calls) saves the context of the interrupted
  8. ;    routine. Assumes that no user registers have been changed
  9. ;    since the interrupt, and that the PC and status register
  10. ;    are still on the stack. Returns the stack pointer being used
  11. ;    at the time of the interrupt **in register a1**.
  12. ;    The fmt parameter is used on the 68000 to communicate the exception
  13. ;    vector number; on >=68010 we use the vector offset from the frame.
  14. ;
  15. ; long save_context(struct context *sav):
  16. ;    Saves the context of the calling routine in the area pointed
  17. ;    to by sav. Save_context always returns 0 when initially called;
  18. ;    this is so processes can (by suitably manipulating the
  19. ;    saved registers) tell when the return from save_context is
  20. ;    actually caused by restoring the context, e.g.:
  21. ;        if (save_context(sav) == 0) {        <<-- L1
  22. ;            /* do some stuff */
  23. ;            sav.regs[D0] = 1;    /* for restore context */
  24. ;            restore_context(sav);    /* goes back to L1 */
  25. ;        }
  26. ;        else /* this is the second time through */
  27. ;
  28. ; void restore_context(struct context *sav):
  29. ;    Restores a context previously saved by build_context or save_context.
  30. ;    Since the program counter is part of the context, this function
  31. ;    will never return (it's like longjmp()).
  32. ;
  33.     TEXT
  34.     
  35.     XDEF    _build_context
  36.     XDEF     _save_context
  37.     XDEF    _restore_context
  38.     XREF    _fpu
  39.     XREF    _framesizes
  40.     XREF    _new_trace    ; from intr.s
  41.     
  42. _build_context:
  43.     move.l    a0,-(sp)    ; save a0; we'll use it for scratch
  44.     move.l    8(sp),a0    ; get address of save area
  45.     movem.l    d0-d7/a0-a6,(a0)    ; save registers D0-D7/A0-A6
  46.     clr.b    C_PTRACE(a0)    ; no pending traces, thanks!
  47.     lea    12(sp),a1    ; start of the interesting stack area
  48.     move.w    (a1)+,d0    ; 68000 fake frame format
  49.     move.w    ($59e).w,d7    ; get process frame flag
  50.     bne.s    nojunk        ; we have some junk on the stack
  51.     move.w    d0,C_SFMT(a0)    ; save fake frame format
  52.     cmp.w    #$8,d0        ; if bus error
  53.     beq.s    group0
  54.     cmp.w    #$c,d0        ; or address error
  55.     bne.s    nojunk
  56. group0:    move.l    (a1)+,C_INTERNAL(a0)    ; stash it in the internal area
  57.     move.l    (a1)+,C_INTERNAL+4(a0)    ; if a debugger's interested
  58. nojunk:
  59.     move.w    (a1)+,d0    ; get SR of context
  60.     move.w    d0,C_SR(a0)    ; save it
  61.     move.l    (a1)+,C_PC(a0)    ; save PC of context
  62.     tst.w    d7        ; test longframe (AKP)
  63.     beq.s    short1        ; short
  64.     tst.w    _fpu        ; is there a true FPU in the system
  65.     beq.s    nofpu
  66.     fsave    C_FSTATE(a0)        ; save internal state frame
  67.     tst.b    C_FSTATE(a0)        ; if NULL frame then the FPU is not in use
  68.     beq.s    nofpu        ; skip programmer's model save
  69.     fmovem.x    fp0-fp7,C_FREGS(a0)        ; save data registers
  70.     fmovem.l    fpcr/fpsr/fpiar,C_FCTRL(a0)    ; and control registers
  71. nofpu:
  72.     lea    C_SFMT(a0),a2
  73.     move.w    (a1)+,d1    ; fetch frame format word
  74.     move.w    d1,(a2)+    ; and stash it away for later
  75.     lsr.w    #8,d1        ; isolate the frame format identifier
  76.     lsr.w    #4,d1
  77.     lea    _framesizes,a3
  78.     move.b    0(a3,d1.w),d1
  79.     bra.s    bcover
  80. bcint:    move.w    (a1)+,(a2)+    ; copy CPU internal state
  81. bcover:    dbf    d1,bcint
  82. short1:
  83.     move.l    a1,C_SSP(a0)    ; a1 now points above the state frame
  84.     move.l    usp,a1        ; save user stack pointer
  85.     move.l    a1,C_USP(a0)
  86.     btst    #13,d0        ; check for supervisor mode
  87.     beq.s    L_CONT1        ; user mode; we already have stack in a1
  88. L_SUPER1:
  89. ; moving from the save state buffer 
  90. ; means not testing longframe again. (AKP)
  91.     move.l    C_SSP(a0),a1    ; was using super stack pointer before interrupt
  92.                 ; 
  93. L_CONT1:
  94.     move.l    ($408).w,C_TERM(a0) ; save GEMDOS terminate vector
  95.     move.l    (sp)+,C_A0(a0)    ; save old register a0
  96.     rts
  97.  
  98. _save_context:
  99.     move.l    a0,-(sp)    ; save a0
  100.     move.l    8(sp),a0    ; get address of context save area
  101.  
  102. ; if running with a true coprocessor we need to save the FPU state
  103.     tst.w    _fpu        ; is there a true FPU in the system
  104.     beq.s    nofpu2
  105.     fsave    C_FSTATE(a0)        ; save internal state frame
  106.     tst.b    C_FSTATE(a0)        ; if NULL frame then the FPU is not in use
  107.     beq.s    nofpu2        ; skip programmer's model save
  108.     fmovem.x    fp0-fp7,C_FREGS(a0)        ; save data registers
  109.     fmovem.l    fpcr/fpsr/fpiar,C_FCTRL(a0)    ; and control registers
  110. nofpu2:
  111. ; note: I am somewhat unsure of this assumption, viz that save_context
  112. ; can never be called in a situation where a co-processor
  113. ; mid-instruction stack frame would be required. I suspect this is a
  114. ; valid assumption, in which case the above FPU code is redundant, the
  115. ; next line is not however!
  116.  
  117.     clr.w    C_SFMT(a0)        ; mark as a 4 word stack frame
  118.     clr.b    C_PTRACE(a0)        ; no pending traces, thanks!
  119.  
  120.     movem.l    d0-d7/a0-a6,(a0)    ; save D0-D7/A0-A6
  121.     lea    8(sp),a1
  122.     move.l    a1,C_SSP(a0)    ; save supervisor stack pointer
  123.                 ; note that it should be pointing above the PC
  124.     move.l    -4(a1),C_PC(a0)    ; save PC
  125.     move.l    usp,a1
  126.     move.l    a1,C_USP(a0)    ; save user stack pointer
  127.     move.w    sr,d0
  128.     move.w    d0,C_SR(a0)    ; save status register
  129.     move.l    ($408).w,C_TERM(a0)    ; save GEMDOS terminate vector
  130.     move.l    (sp)+,C_A0(a0)    ; save old a0
  131.     moveq.l    #0,d0        ; return 0
  132.     rts
  133.  
  134. _restore_context:
  135.     ori.w    #$0700,sr    ; mask interrupts
  136.     move.l    4(sp),a0    ; address of context save area
  137.     move.l    C_SSP(a0),sp    ; supervisor stack pointer
  138.     move.l    C_USP(a0),a1
  139.     move.l    a1,usp        ; set user stack pointer
  140.     move.l    C_TERM(a0),($408).w    ; restore GEMDOS terminate vector
  141.  
  142.     tst.w    ($59e).w    ; test longframe (AKP)
  143.     beq.s    short3
  144.     moveq.l    #0,d0
  145.     lea    C_SFMT(a0),a1
  146.     move.w    (a1)+,d0    ; fetch frame format word
  147.     move.w    d0,d1        ; copy it for later
  148.     lsr.w    #8,d1        ; isolate the frame format identifier
  149.     lsr.w    #4,d1
  150.     lea    _framesizes,a2
  151.     move.b    0(a2,d1.w),d1
  152.     sub.w    d1,sp
  153.     sub.w    d1,sp
  154.     move.l    sp,a2
  155.     bra.s    rcover
  156. rcint:    move.w    (a1)+,(a2)+
  157. rcover:    dbf    d1,rcint
  158.     move.w    d0,-(sp)    ; frame format identifier
  159. ; if running with a true coprocessor we need to restore the FPU state
  160.  
  161.     tst.w    _fpu        ; is there a true FPU in the system
  162.     beq.s    short3
  163.     tst.b    C_FSTATE(a0)        ; if NULL frame then the FPU is not in use
  164.     beq.s    short7        ; skip programmer's model restore
  165.     fmovem.l    C_FCTRL(a0),fpcr/fpsr/fpiar    ; restore control registers
  166.     fmovem.x    C_FREGS(a0),fp0-fp7        ; and data registers
  167. short7:    frestore    C_FSTATE(a0)            ; finally the internal state
  168. short3:
  169.     move.l    C_PC(a0),-(sp)    ; push the PC
  170.     move.w    C_SR(a0),d0    ; fetch status register
  171.     move.w    d0,-(sp)    ; push the status register
  172.     tst.b    C_PTRACE(a0)        ; check for a pending trace
  173.     movem.l    (a0),d0-d7/a0-a6    ; restore registers d0-d7/a0-a6
  174.     beq.s    notrace
  175.     jmp    _new_trace
  176. notrace:
  177.     rte            ; jump back to old context
  178.  
  179.     END
  180.